import {
  BoundingSphere, Cartesian3, defined, HeadingPitchRange, Math as CesiumMath, SceneMode,
} from 'cesium/Cesium';
import NavigationControl from './NavigationControl';
import Utils from '../core/Utils';

/**
 * 指北
 *
 * @alias CompassNavigationControl
 * @constructor
 * @abstract
 *
 * @param {Terria} terria The Terria instance.
 */
const CompassNavigationControl = function (terria) {
  NavigationControl.apply(this, arguments);

  this.name = '指 北';
  this.isHeading = true;
  /**
   * Gets or sets the CSS class of the control. This property is observable.
   * @type {String}
   */
  this.cssClass = 'navigation-control-icon-compass';
};
CompassNavigationControl.prototype = Object.create(NavigationControl.prototype);

CompassNavigationControl.prototype.reduceCompass = function () {
  this.isActive = true;
  const centerScratch = new Cartesian3();
  if (defined(this.terria)) {
    const { scene } = this.terria;
    const { camera } = scene;
    const sscc = scene.screenSpaceCameraController;

    if (scene.mode === SceneMode.MORPHING || !sscc.enableInputs) {
      return true;
    }

    if (scene.mode === SceneMode.COLUMBUS_VIEW && !sscc.enableTranslate) {
      return;
    }

    if (scene.mode === SceneMode.SCENE3D || scene.mode === SceneMode.COLUMBUS_VIEW) {
      if (!sscc.enableLook) {
        return;
      }

      if (scene.mode === SceneMode.SCENE3D) {
        if (!sscc.enableRotate) {
          return;
        }
      }
    }

    const center = Utils.getCameraFocus(this.terria, true, centerScratch);
  

    const cameraPosition = scene.globe.ellipsoid.cartographicToCartesian(camera.positionCartographic, new Cartesian3());

    const surfaceNormal = scene.globe.ellipsoid.geodeticSurfaceNormal(center);
    if (this.terria.options.setDefaultTrigger) {
      this.terria.options.setDefaultTrigger();
    }

    const focusBoundingSphere = new BoundingSphere(center, 0);
    camera.flyToBoundingSphere(focusBoundingSphere, {
      offset: new HeadingPitchRange(
        0,
        // do not use camera.pitch since the pitch at the center/target is required
        CesiumMath.PI_OVER_TWO - Cartesian3.angleBetween(
          surfaceNormal,
          camera.directionWC,
        ),
        // distanceToBoundingSphere returns wrong values when in 2D or Columbus view so do not use
        // camera.distanceToBoundingSphere(focusBoundingSphere)
        // instead calculate distance manually
        Cartesian3.distance(cameraPosition, center),
      ),
      duration: 1.5,
    });
  }
  this.isActive = false;
};

CompassNavigationControl.prototype.activate = function () {
  this.reduceCompass();
};

export default CompassNavigationControl;
